#!/usr/bin/env python2
# -*- coding: utf-8 -*-


import sys
import re
import traceback
from pprint import pprint

from Ump.common import exception
from Ump.umptypes import UmpPath


# from pyvalid.validators import is_validator
# import validators


reload(sys)
sys.setdefaultencoding('utf-8')


def to_int(i, default=None):
    try:
        res = int(i)
    except Exception:
        traceback.print_exc()
        if default is not None:
            res = default
        else:
            raise exception.InvalidParameter(where='to_int', i=i)
    return res


class Validator(object):
    _username_pattern = re.compile('^[a-z0-9-_]{3,16}$')

    # paging

    @classmethod
    def check_skip(cls, value):
        return value

    @classmethod
    def check_limit(cls, value):
        return value

    @classmethod
    def check_order(cls, value):
        return value

    @classmethod
    def check_desc(cls, value):
        return value

    # string pattern

    @classmethod
    def check_unit(cls,value):
        if value in ['days', 'hours', 'minutes']:
            return value
        else:
            raise exception.InvalidParameter("value belong to ['days','hours','minutes']")

    @classmethod
    def check_count(cls, value):
        m = re.match('[1-9][0-9]*', value)
        if m.group(0) == value:
            return value

    @classmethod
    def check_username(cls, value):
        m = cls._username_pattern.match(value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(username=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_password(cls, value):
        m = re.match('^\w{3,16}$', value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(password=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_name(cls, value):
        m = cls._username_pattern.match(value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(name=value, pattern=cls._username_pattern.pattern)

    @classmethod

    def check_new_password(cls, value):
        return cls.check_password(value)

    @classmethod
    def check_chap_name(cls, value):
        m = re.match('^[a-z0-9-_]{12,16}$', value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(chap_name=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_vgroup_name(cls, value):
        m = re.match('^[0-9a-zA-Z-_]+$', value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(vgroup_name=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_folder_name(cls, value):
        m = cls._username_pattern.match(value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(folder_name=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_volume_ids(cls, value):
        m = re.match('^([1-9][0-9]*)(,[1-9][0-9]*)+$', value)
        if m:
            return value
        raise exception.InvalidParameter(volume_ids=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_vgroup_id(cls, value):
        m = re.match('^[1-9][0-9]*$', value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(vgroup_id=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_cgsnapshot_name(cls, value):
        m = re.match('^[0-9a-zA-Z-_]+$', value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(cgsnapshot_name=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_chap_password(cls, value):
        """
        :param value: len [12-16]
        :return:
        """
        m = re.match('^\w{12,16}$', value)
        if m.group(0) == value:
            return value
        raise exception.InvalidParameter(password=value, pattern=cls._username_pattern.pattern)

    @classmethod
    def check_path(cls, value):
        return value

    @classmethod
    def check_pool_path(cls, value):
        path = UmpPath(value)
        if path.is_pool():
            return value
        raise exception.InvalidParameter(path=value, format='a')

    @classmethod
    def check_volume_path(cls, value):
        path = UmpPath(value)
        if path.is_volume():
            return value
        raise exception.InvalidParameter(path=value, format='a/b')

    @classmethod
    def check_snap_path(cls, value):
        path = UmpPath(value)
        if path.is_snapshot():
            return value
        raise exception.InvalidParameter(path=value, format='a/b@c')

    @classmethod
    def check_add_volume_list(cls, value):
        return value

    @classmethod
    def check_remove_volume_list(cls, value):
        return value

    # range

    @classmethod
    def check_protocol(cls, value):
        if value in ['iscsi', 'nbd', 'lichbd']:
            return value
        raise exception.InvalidParameter(protocol=value, range=['iscsi', 'nbd', 'lichbd'])

    @classmethod
    def check_role(cls, value):
        if value in ['administrator', 'tenancy']:
            return value
        raise exception.InvalidParameter(role=value, range=['administrator', 'tenancy'])

    @classmethod
    def check_provisioning(cls, value):
        if value in ['thin', 'thick']:
            return value
        raise exception.InvalidParameter(provisioning=value, range=['thin', 'thick'])

    # bool

    @classmethod
    def check_bool(cls, value):
        return value

    @classmethod
    def check_value(cls, value):
        return value

    @classmethod
    def check_is_protect(cls, value):
        if value == 'True':
            value = True
        elif value == 'False':
            value = False
        else:
            value = False
        return value

    # number

    @classmethod
    def check_size(cls, value):
        value = to_int(value)
        if 0 < value <= 8*1024:
            value *= (1024 ** 3)
            return value
        raise exception.InvalidParameter(size=value, range='0 < size <= 8T')

    @classmethod
    def check_unit(cls, value):
        return value

    @classmethod
    def check_ec_data(cls,value):
        return value

    @classmethod
    def check_ec_code(cls, value):
        return value

    @classmethod
    def check_repnum(cls, value):
        value = to_int(value)
        if value in [2, 3, 4]:
            return value
        raise exception.InvalidParameter(repnum=value, range=[2, 3, 4])

    @classmethod
    def check_quota(cls, value):
        value = to_int(value)
        if value >= 0:
            return value
        raise exception.InvalidParameter(quota=value, range='quota >= 0')

    # ID

    @classmethod
    def check_protection_domain_ids(cls, value):
        if isinstance(value, (str, unicode)):
            l = value.split(',')
            return [to_int(x.strip()) for x in l]
        elif isinstance(value, list):
            return [to_int(x) for x in value]
        raise exception.InvalidParameter(protection_domain_ids=value, range='1,2 or list of integer')

    @classmethod
    def check_protection_domain_id(cls, value):
        return to_int(value)

    # FUNC

    @classmethod
    def _check_func(cls, param):
        funcname = 'check_%s' % param
        return getattr(cls, funcname)

    @classmethod
    def check(cls, name, value):
        f = cls._check_func(name)
        if not f:
            raise exception.CheckFunNotDefined(name)
        return f(value)


if __name__ == '__main__':
    pprint(globals())

    print Validator.check('quota', {})
